using System.Collections.Generic;
using System.Diagnostics;
using System.Web.Mvc;
using BLL.Services;
using BLL.Services.Comments;
using BLL.Services.Comments.Listing;
using MvcContrib.Sorting;
using MvcContrib.UI.Grid;
using Web.Areas.Admin.Infrastructure;
using Web.Areas.Admin.Models.Comments;
using Web.Infrastructure;
using Web.Infrastructure.Models;
using Web.Infrastructure.Security;

namespace Web.Areas.Admin.Controllers
{
    [AdminAuthorization]
    public partial class CommentsController : AdminController
    {
        private readonly ICommentsService _commentsService;

        public CommentsController(ICommentsService commentsService)
        {
            _commentsService = commentsService;
        }

        public virtual ActionResult Index()
        {
            return BackBoneView(MVC.Admin.Shared.Views.Empty);
        }

        public virtual ActionResult ListingTemplate()
        {
            return BackBoneView(MVC.Admin.Comments.Views.Listing);
        }

        [ListingAction("Description")]
        public virtual ActionResult Listing(
            GridSortOptions sort, int size, int page, CommentFilter filter)
        {
            var model = _commentsService.GetListingComments(
                page, size, sort.Column, sort.Direction != SortDirection.Descending ? 0 : 1, filter);
            return BackBoneJson(model);
        }

        [HttpGet]
        public virtual ActionResult Create()
        {
            return BackBoneView(MVC.Admin.Shared.Views.Empty);
        }

        [HttpGet]
        public virtual ActionResult CreateTemplate()
        {
            return BackBoneView(MVC.Admin.Comments.Views.Create, new CommentCreateModel());
        }

        [HttpPost]
        public virtual ActionResult Create(CommentCreateModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Errors = GetErrors;
                return Json(model);
            }
            var comment = (Comment)model;
            try
            {
                _commentsService.Create(comment);
                model.SuccessMessage = "Comment has been successfully created.";
                return Json(model);
            }
            catch (ServiceException exception)
            {
                ModelState.AddModelError(string.Empty, exception.Message);
                model.Errors = GetErrors;
                return Json(model);
            }
        }

        [HttpGet]
        public virtual ActionResult Edit(int? commentId)
        {
            var model = new CommentEditModel();
            if (!commentId.HasValue)
            {
                model.Errors = new List<ErrorModel>
                    {
                        new ErrorModel("Empty value")
                    };
                return BackBoneJson(model);
            }
            var comment = _commentsService.GetCommentById(commentId.Value);

            if (null == comment)
            {
                model.Errors = new List<ErrorModel>
                    {
                        new ErrorModel("Comment with commentId = " + commentId + " was not found.")
                    };
                return BackBoneJson(new CommentEditModel());
            }

            model = new CommentEditModel(comment);

            return BackBoneJson(model);
        }

        [HttpGet]
        public virtual ActionResult EditTemplate()
        {
            return BackBoneView(MVC.Admin.Comments.Views.Edit, new CommentEditModel());
        }

        [HttpPost]
        public virtual ActionResult Edit(int? commentId, CommentEditModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Errors = GetErrors;
                return Json(model);
            }

            var comment = (Comment)model;
            try
            {
                _commentsService.Save(comment);
                model.SuccessMessage = "Comment has been successfully updated.";
                return Json(model);
            }
            catch (ServiceException exception)
            {
                ModelState.AddModelError(string.Empty, exception.Message);
                model.Errors = GetErrors;
                return Json(model);
            }
        }

        public virtual ActionResult Delete(int[] commentIds)
        {
            var model = new BaseModel();
            foreach (var commentId in commentIds)
            {
                try
                {
                    _commentsService.Delete(commentId);
                }
                catch (ServiceException exception)
                {
                    ModelState.AddModelError(string.Empty, exception.ToString());
                    Trace.TraceError(exception.ToString());
                }
            }
            model.Errors = GetErrors;
            if (ModelState.IsValid)
            {
                model.SuccessMessage = "Comment have been successfully deleted.";
            }
            return Json(model);
        }
    }
}